home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************
- * File: stardate.c
- * Author: Jay Windley (modified by Yves Perrenoud)
- * Created: 1 Jan 92 (modified 19 Dec 94)
- * Copyright: (c) 1 Jan 92 by Jay Windley
- * Description: prints the current stardate to stdout
- *
- *************************************************************/
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <time.h>
-
- #define FIT(x,y) while((x)<0)(x)+=(y);while((x)>(y))(x)-=(y)
-
- #define MAXPRECISION 7
- #define OUTPUTFORMAT "%%%03d.%df"
-
- /*---------------------------------------------------------------------*
- *TAG ( julian_day );
- *---------------------------------------------------------------------*
- * Returns the New Epoch Julian Day for the given Gregorian calendar
- * day.
- */
- double julian_day (month, day, year)
- int month, day, year;
- {
- int loc_month;
- int loc_year;
- int a, b, c, d;
-
- loc_month = month;
- loc_year = year;
-
- /* correct for March-based B.C. year */
- if (year < 0) loc_year ++;
- if (month < 3) {
- loc_month = month + 12;
- loc_year --;
- }
-
- /* set up A and B for Julian to Gregorian calendar change */
- if (year < 1582) b = 0;
- else if (year == 1582) {
- if (month < 10) b = 0;
- else if (month == 10) {
- if (day < 15) b = 0;
- else {
- a = loc_year / 100;
- b = 2 - a + (a/4);
- }
- } else {
- a = loc_year / 100;
- b = 2 - a + (a/4);
- }
- } else {
- a = loc_year / 100;
- b = 2 - a + (a/4); /* century is set up */
- }
-
- /* fudge for year and month */
- c = (int) (365.25 * loc_year) - 694025;
- d = (int) (30.6001 * (loc_month + 1));
-
- return (double) (b + c + d + day) - .5;
- }
-
- /*---------------------------------------------------------------------*
- *TAG ( sidereal );
- *---------------------------------------------------------------------*
- * Returns Greenwich Mean Sidereal Time for the given Greenwich Mean
- * Solar Time on the given NE Julian Day.
- */
- double sidereal (gmt, jd, gyear)
- double gmt; /* Greenwich Mean Time, decimal */
- double jd; /* Julian Day */
- int gyear; /* calendar year */
- {
- register double dayfudge, yrfudge, jhund;
- double initjd, hourfudge, time0, lst;
-
- /* find Julian century at start of year */
- initjd = julian_day (1, 0, gyear);
- jhund = initjd / 36525.0;
-
- /* apply polynomial correction */
- dayfudge = 6.6460656 + (0.051262 + (jhund * 0.00002581)) * jhund;
- yrfudge = 2400.0 * (jhund - ( (double) (gyear - 1900) / 100));
- hourfudge = 24.0 - dayfudge - yrfudge;
- time0 = (jd - initjd) * 0.0657098 - hourfudge;
-
- /* adjust to modulo 24 hours */
- lst = (gmt * 1.002737908) + time0;
- FIT (lst, 24.0);
- return lst;
- }
-
- /*---------------------------------------------------------------------*
- *TAG ( main );
- *---------------------------------------------------------------------*
- * Behaves as expected.
- */
- void main (argc, argv)
- int argc;
- char *argv[];
- {
- int timezone=0,i;
- int jd, precis;
- double gmt, gmst;
- time_t t;
- struct tm *tm;
- char buf[16];
- char fmt[16];
-
- /* Parsing below rewritten by Yves Perrenoud based on the original code */
-
- if (argc > 1)
- {
- for (i=1;i <= (argc-1);i++)
- {
- if (argv[i][0] == '-')
- {
- switch (argv[i][1])
- {
- case 'd' : if (sscanf (&argv[i][2], "%d", &precis) < 1)
- {
- fprintf (stderr, "%s: invalid precision specification\n", argv[0]);
- exit (1);
- }
- if (precis < 1) precis = 1;
- if (precis > MAXPRECISION) precis = MAXPRECISION;
- break;
- case 't' : if (sscanf (&argv[i][2], "%d", &timezone) < 1)
- {
- fprintf (stderr, "%s: invalid timezone specification\n", argv[0]);
- exit (1);
- }
- if (timezone < -12) timezone = -12;
- if (timezone > 12) timezone = 12;
- break;
- case 'h' : puts("options:");
- puts(" -d<prec> : precision from 1 to 7");
- puts(" -t<tz> : timezone from -12 to 12");
- exit(0);
- break;
- default : puts("Uknown type of OPTION"); exit(1);
- }
- }
- }
- } else precis = 1;
-
-
- /* timezone modifications made by Yves Perrenoud for Amiga compatibility */
-
- t = time (NULL);
- tm = localtime (&t);
- jd = julian_day (tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900);
- gmt = (double) tm->tm_hour - timezone +
- tm->tm_min / 60.0 +
- tm->tm_sec / 3600.0;
- gmst = sidereal (gmt, (double) jd, tm->tm_year);
- sprintf (fmt, OUTPUTFORMAT, precis + 6, precis);
- sprintf (buf, fmt, (double) jd + gmst / 24.0);
- puts (buf);
- }
-